/*
   trait 类似于Java中的接口
*/
#[test]
pub fn main() {
    let circle = Circle { radius: 5.0 };
    let rectangle = Rectangle {
        width: 10.0,
        height: 4.0,
    };

    print_area1(&circle);
    print_area2(&rectangle);

    let shapes: Vec<&dyn Shape> = vec![&circle, &rectangle];
    print_area3(&shapes);
}
// 定义方法，使用泛型trait。以下方法是等同的。
pub fn print_area1<S: Shape>(shape: &S) {
    println!("【1】The area is: {}", shape.area());
}

pub fn print_area2(shape: &impl Shape) {
    println!("【2】The area is: {}", shape.area());
}

// 也可以实现运行时的多态：
pub fn print_area3(shapes: &[&dyn Shape]) {
    for shape in shapes {
        println!("【3】The area is: {}", shape.area());
    }
}

// 1.定义一个trait。
pub trait Shape {
    fn area(&self) -> f64;
}

// 2.定义数据结构【圆形和矩形】
pub struct Circle {
    pub radius: f64,
}

pub struct Rectangle {
    pub width: f64,
    pub height: f64,
}

// 3.实现trait。for表示泛型。
impl Shape for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

impl Shape for Rectangle {
    fn area(&self) -> f64 {
        self.width * self.height
    }
}